package com.andox.fn.inf.rpc.rest.protocol.registry;

import java.util.List;
import java.util.Map;

import com.andox.fn.inf.rpc.rest.config.ReferenceConfig;
import com.andox.fn.inf.rpc.rest.config.ServiceConfig;
import com.andox.fn.inf.rpc.rest.extension.ExtensionLoader;
import com.andox.fn.inf.rpc.rest.util.RegistryUtil;
import com.google.common.collect.Maps;


public class DefaultRegistryService implements RegistryService{

	private Map<String /** protocol **/, Map<String /** connection **/, RegistryImpl>> registryImplTable = Maps.newConcurrentMap();
	
	@Override
	public void start() {
		
	}

	@Override
	public void close() {
		
	}

	private RegistryImpl lookupRegistryImpl(String registry) {
		String protocol = RegistryUtil.findRegistryProtocol(registry);
		RegistryImpl registryImpl = null;
		Map<String, RegistryImpl> x = this.registryImplTable.get(protocol);
		if (x == null) {
			synchronized (this) {
				if (x == null) {
					x = Maps.newConcurrentMap(); 
					this.registryImplTable.put(protocol, x);
				}
			}
		}
		
		String connection = RegistryUtil.findRegistryConnection(registry);
		registryImpl = x.get(connection);
		if (registryImpl == null) {
			synchronized (this) {
				if (registryImpl == null) {
					registryImpl = ExtensionLoader.getExtensionLoader(RegistryImpl.class).getExtension(protocol);
					registryImpl.setConnection(connection);
					registryImpl.start();
					
					x.put(connection, registryImpl);
				}
			}
		}
		
		return registryImpl;
	}
	
	@Override
	public List<ReferenceConfig> subscribe(ReferenceConfig referenceConfig, RegistryNotify rn) {
		return lookupRegistryImpl(referenceConfig.getRegistry()).subscribe(referenceConfig, rn);
	}

	@Override
	public void unsubscribe(ReferenceConfig referenceConfig) {
		//
	}

	@Override
	public void register(ServiceConfig serviceConfig) {
		this.lookupRegistryImpl(serviceConfig.getRegistry()).register(serviceConfig);
	}

	@Override
	public void unregister(ServiceConfig serviceConfig) {
		
	}

	@Override
	public List<ServiceConfig> lookup(ReferenceConfig referenceConfig) {
		return null;
	}

}
